package main

import (
	"github.com/lab-online/internal/course/infra/model"
	"github.com/lab-online/pkg/logger"
	baseModel "github.com/lab-online/pkg/model"
	"github.com/lab-online/pkg/util"
	"gorm.io/gorm"
)

type CourseExperiment struct {
	ID    uint   `json:"id"`
	Meta  string `json:"meta"`
	Index uint   `json:"index"`
}

type Course struct {
	ID          uint               `json:"id"`
	Name        string             `json:"name"`
	Description string             `json:"description"`
	Experiments []CourseExperiment `json:"experiments"`
}

type Experiment struct {
	ID          uint   `json:"id"`
	Name        string `json:"name"`
	Description string `json:"description"`
	Queue       string `json:"queue"`
}

type CourseSchema struct {
	CourseUpdateMode string       `json:"courseUpdateMode"`
	Courses          []Course     `json:"courses"`
	Experiments      []Experiment `json:"experiments"`
}

func setupCourse(db *gorm.DB, data *Initial) {
	courseSchema := &data.Course
	courseExperiments, courses, experiments := transformCourseSchema(courseSchema)

	// 重建关联表
	db.Delete(&model.CourseExperiment{}, "1=1")
	db.Save(courseExperiments)

	switch courseSchema.CourseUpdateMode {
	case "overwrite":
		db.Save(courses)
		db.Save(experiments)
	case "skip":
		for _, course := range courses {
			query := &model.Course{}
			query.ID = course.ID
			db.FirstOrCreate(course, query)
		}

		for _, experiment := range experiments {
			query := &model.Experiment{}
			query.ID = experiment.ID
			db.FirstOrCreate(experiment, query)
		}
	default:
		logger.Error("unknown mode", courseSchema.CourseUpdateMode)
	}
}

func transformCourseSchema(
	courseSchema *CourseSchema,
) ([]*model.CourseExperiment, []*model.Course, []*model.Experiment) {
	courseExperimentModels := []*model.CourseExperiment{}
	for _, course := range courseSchema.Courses {
		courseExperimentModels = append(courseExperimentModels, util.SliceMap(course.Experiments,
			func(experiment CourseExperiment) *model.CourseExperiment {
				return &model.CourseExperiment{
					ExperimentID: experiment.ID,
					CourseID:     course.ID,
					Meta:         experiment.Meta,
					Index:        experiment.Index,
				}
			})...,
		)
	}

	return courseExperimentModels,
		util.SliceMap(courseSchema.Courses, func(course Course) *model.Course {
			return &model.Course{
				BaseModel: baseModel.BaseModel{
					ID: course.ID,
				},
				Name:        course.Name,
				Description: course.Description,
			}
		}),
		util.SliceMap(courseSchema.Experiments, func(experiment Experiment) *model.Experiment {
			return &model.Experiment{
				BaseModel: baseModel.BaseModel{
					ID: experiment.ID,
				},
				Name:        experiment.Name,
				Description: experiment.Description,
				Queue:       experiment.Queue,
			}
		})
}
